// 皇女极限解析
// 武器推荐  天空 > 绝弦 > 阿莫斯  
// 90级面板
// 白值:244, 暴击率:5, 暴击伤害:50, 攻击力加成: 24
// 命座效果  e多额外200% q多额外222% 奥兹协同攻击 30%

// 圣遗物选择雷4 雷伤+15 雷四件套效果
// 初始副词条取最优 攻攻双暴 攻双暴 攻双暴 攻攻双暴 攻攻爆  // 副词条效果与主词条效果不重复 每个圣遗物5次强化副词条全排列取最优结果 

// 这里取得输出是 e召唤 q伤害 e喷射15次 协同攻击15次 天赋圣裁之雷7次



// 阿莫斯  608白值  49.6攻击  效果对后台皇女没用
// 攻击 雷伤 暴击         副词 暴击率:46.8(12)  暴击伤害:101.4(13) 
// 数值 攻击力 2460.7  暴击98.5  爆伤190.4
// 46.6雷伤杯   15雷伤(雷套)
// e召唤平均期望  20993
// e后续喷射 8232
// q  30667
// 奥兹协同攻击 1543
// 圣雷 4116
// 总 227123

// 绝弦  510白值 165精通 48 eq增伤
// 攻击 雷伤 暴击         副词 暴击率:46.8(12)  暴击伤害:101.4(13) 
// 数值 攻击力 1848  暴击98.5  爆伤190.4
// 46.6雷伤杯   15雷伤(雷套)   48eq增伤
// e召唤平均期望  20451
// e后续喷射 8020
// q  29875
// 奥兹协同攻击 1503
// 圣雷 4010
// 总 221259   精通打反应伤害更高 优于阿莫斯


// 天空 674白值  22.1暴击  40爆伤 2s一次 攻击力x1.25 物理伤害

// 攻击 雷伤 暴击     副词 攻击力:23.2(4) 暴击率:23.4(6)  暴击伤害:117(15) 
// 数值 攻击力 2379  暴击97.2  爆伤246
// 46.6雷伤杯   15雷伤(雷套)
// e召唤平均期望  23936
// e后续喷射 9386  
// q  34966
// 奥兹协同攻击 1760
// 圣雷 4693   
// 总 258961   + 4538 x n次 天空特效(后台不知道能不能触发)


let charaters = {
    hn : {
        name: "lv90皇女", 
        base: 244,
        attRate: 24,
        criticalRate: 5,
        criticalStrike: 50
    }
}

let weapons = {
    tiankj: {
        name:"lv90天空弓",  // 每两秒 一次 1.25 * 攻击力 物理伤害
        base: 674,
        criticalRate: 22.1,
        criticalStrike:40
    },
    amosi: {
        name: "lv90阿莫斯",  // 普攻蓄力24增伤
        base: 608,
        attRate:49.6
    },
    juexian: {
        name: "lv90绝弦",  // 技能大招 48 增伤
        base: 510,
        "精通":165
    }
}
let normal_clips = calc_clips_normal();
let normal_clips2 = calc_clips_normal(2);
let charactersDmg = []

// 皇女绝弦
charactersDmg.push(getDMG([charaters.hn,weapons.juexian,{fixedAtt:311,criticalRate:31.1,dmgRate:46.6,attRate:46.6},normal_clips], (data,second) => {
    // 雷套
    // 15增伤 反应增伤(暂时忽略)
    data.dmgRate += 15;
    let attack = data.base *(1 + data.attRate/100) + data.fixedAtt
    let edmg = getDmgDps({...data,dmgRate:data.dmgRate + 48}, 2.08 + 2) * q(10) * df(90,90); // e
    let ep = getDmgDps({...data,dmgRate:data.dmgRate + 48}, 1.6) * q(10) * df(90,90); // 奥兹喷
    let qd = getDmgDps({...data,dmgRate:data.dmgRate + 48}, 3.74 + 2.22) * q(10) * df(90,90); // q
    let xt =  getDmgDps({...data,dmgRate:data.dmgRate + 48}, 0.3) * q(10) * df(90,90); // 协同攻击
    let sl =  getDmgDps({...data,dmgRate:data.dmgRate + 48}, 0.8) * q(10) * df(90,90); // 圣裁之雷
    let ret = edmg + qd + ep*15 + xt * 15 + sl * 7
    return {point:ret, data, second, attack ,edmg,ep,qd,xt,sl}
}))

// 皇女阿莫斯
charactersDmg.push(getDMG([charaters.hn,weapons.amosi,{fixedAtt:311,criticalRate:31.1,dmgRate:46.6,attRate:46.6},normal_clips], (data,second) => {
    // 雷套
    // 15增伤 反应增伤(暂时忽略)
    data.dmgRate += 15;
    let attack = data.base *(1 + data.attRate/100) + data.fixedAtt
    let edmg = getDmgDps(data, 2.08 + 2) * q(10) * df(90,90); // e
    let ep = getDmgDps(data, 1.6) * q(10) * df(90,90); // 奥兹喷
    let qd = getDmgDps(data, 3.74 + 2.22) * q(10) * df(90,90); // q
    let xt =  getDmgDps(data, 0.3) * q(10) * df(90,90); // 协同攻击
    let sl =  getDmgDps(data, 0.8) * q(10) * df(90,90); // 圣裁之雷
    let ret = edmg + qd + ep*15 + xt * 15 + sl * 7
    return {point:ret, data, second, attack ,edmg,ep,qd,xt,sl}
}))

// 皇女天空
charactersDmg.push(getDMG([charaters.hn,weapons.tiankj,{fixedAtt:311,criticalRate:31.1,dmgRate:46.6,attRate:46.6},normal_clips], (data,second) => {
    // 雷套
    // 15增伤 反应增伤(暂时忽略)
    data.dmgRate += 15;
    let attack = data.base *(1 + data.attRate/100) + data.fixedAtt
    let edmg = getDmgDps(data, 2.08 + 2) * q(10) * df(90,90); // e
    let ep = getDmgDps(data, 1.6) * q(10) * df(90,90); // 奥兹喷
    let qd = getDmgDps(data, 3.74 + 2.22) * q(10) * df(90,90); // q
    let xt =  getDmgDps(data, 0.3) * q(10) * df(90,90); // 协同攻击
    let sl =  getDmgDps(data, 0.8) * q(10) * df(90,90); // 圣裁之雷
    let tk = getDmgDps({...data, dmgRate:0}, 1.25) * q(10) * df(90,90); // 天空特效
    let ret = edmg + qd + ep*15 + xt * 15 + sl * 7
    return {point:ret, data, second, attack ,edmg,ep,qd,xt,sl,tk}
}))

console.log(charactersDmg.sort((a,b)=>b.point-a.point));


function getDMG(dataarr, getRet){
    let chance = 25;
    let _ret = [];
    for (let index = 0; index <= chance; index++) {
        let criticalStrike = index; 
        for (let index2 = 0; index2 <= chance - index; index2++) {
            let criticalRate = index2;
            for (let index3 = 0; index3 <= chance-index-index2; index3++) {
                let attRate = index3;
                let defenceRate = chance - index - index2 - index3;
                _ret.push({
                    defenceRate: 7.3 * defenceRate,
                    attRate:5.8 * attRate,
                    criticalRate:3.9 * criticalRate,
                    criticalStrike:7.8 * criticalStrike
                });
            }
        }
    }
    _ret = _ret.map(second => {
        let panel = getPanel([...dataarr, second]);
        return  getRet(panel, second)
    })
    _ret.sort((b,a)=> a.point-b.point)
    return _ret[0]
}

function getDmgDps(data, rate=1){
    let criticalRate = data.criticalRate
    if(criticalRate > 100){criticalRate = 100}
    let baseat = data.base * (1 + data.attRate/100) + data.fixedAtt;
    let bdmg = baseat * (1 + data.criticalStrike/100);
    let bdps = (criticalRate * 10 * bdmg + (1000-criticalRate * 10)*baseat)/1000
    let adddmg = bdps * (1 + data.dmgRate/100)
    return adddmg * rate
}

function getPanel(arr){
    let info = {name1:"",name2:""};
    arr.forEach((item, i)=>{
        if(item.name){
            info["name" + (i+1)] = item.name
        }
        for (const key in item) {
            if(key !== "name"){
                if(info[key]){
                    info[key] += item[key]
                } else {
                    info[key] = item[key]
                }
            }
        }
    })
    return info
}

function q (resistance) {
    if(resistance < 0) {
        return 1 - resistance/200
    } else if (resistance >=0 && resistance < 75){
        return 1 - resistance/100
    } else {
        return 1/(1+resistance/100*4)
    }
}

function df(youLv=0, eLv=0, td){
    return (100+youLv)/(100+youLv+(100+eLv)*(td? (100-td)/100 : 1))
}

// 固定攻击力 19  防御力23 生命值299 5.3% 
function calc_clips_normal (n) {
    let clips = [
        {
            fixedAtt: 19,
            attRate: 5.8,
            criticalRate: 3.9,
            criticalStrike:7.8
        },
        {
            attRate: 5.8,
            criticalRate: 3.9,
            criticalStrike:7.8
        },
        {
            fixedAtt: 19,
            criticalRate: 3.9,
            criticalStrike:7.8
        },
        {
            fixedAtt: 19,
            attRate: 5.8,
            criticalRate: 3.9,
            criticalStrike:7.8
        },
        {
            fixedAtt: 19,
            attRate: 5.8,
            criticalRate:n!=2? 0:3.9,
            criticalStrike:n!=2? 7.8:0
        }
    ]
    let data = {}
    clips.forEach(item => {
        for (const key in item) {
            data[key] = data[key]? (data[key]+item[key]) : item[key]
        }
    })
    return data
}

